﻿package net.nicoptere.project 
{
	import flash.events.Event;
	import flash.events.ErrorEvent;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLLoaderDataFormat;
	import net.nicoptere.utils.StringUtil;
	/**
	 * @author nicolas barradeau
	 */
	dynamic public class Config extends EventDispatcher
	{
		
		protected var debug:Boolean = false;
		
		public var xmlResults:XML;
		public var progressBar:*;
		private static var _instance:Config;
		
		public function Config( configUrl:String = '' ) 
		{
			//trace( 'Config.init' );
			_instance = this;
			if ( configUrl != '' )
			{
				load( configUrl );
			}
		}
		
		public static function load( configUrl:String ):void
		{
			if( _instance.debug ) trace( 'Config.load' );
			var req:URLRequest = new URLRequest(configUrl);
			var xmlLoader:URLLoader = new URLLoader();
			instance.configureListeners( xmlLoader );
			xmlLoader.load( req  );
			
		}
		
		public static function get instance():Config
		{
			if ( _instance != null ) return _instance;
			_instance = new Config();
			return _instance;
		}
		
		
		//configureListeners
		private function configureListeners(dispatcher:IEventDispatcher):void
		{
            
			if( debug ) trace( 'Config.configureListeners' );
			dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
            dispatcher.addEventListener(ErrorEvent.ERROR, errorHandler);
            dispatcher.addEventListener(Event.COMPLETE, completeHandler);
            dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler );
			
        }
		private function removeListeners(dispatcher:IEventDispatcher):void
		{
            
			if( debug ) trace( 'Config.removeListeners' );
			dispatcher.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            dispatcher.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
            dispatcher.removeEventListener(ErrorEvent.ERROR, errorHandler);
            dispatcher.removeEventListener(Event.COMPLETE, completeHandler );
            dispatcher.removeEventListener(ProgressEvent.PROGRESS, progressHandler );
			
        }
		
		/*
		*     Listener ERROR HANDLER
		*/
        private function securityErrorHandler(event:SecurityErrorEvent):void
		{
			if( debug ) trace('Config.SecurityError');
			dispatchEvent( new ErrorEvent( ErrorEvent.ERROR ) );
			removeListeners( event.target as IEventDispatcher );
		}
		private function httpStatusHandler(event:HTTPStatusEvent):void
		{
			if( debug ) trace('Config.HTTPerror');
			dispatchEvent( new ErrorEvent( ErrorEvent.ERROR ) );
			removeListeners( event.target as IEventDispatcher );
		}
		private function ioErrorHandler(event:IOErrorEvent):void
		{
			if( debug ) trace('Config.IOerror', event.toString());
			dispatchEvent( new ErrorEvent( ErrorEvent.ERROR ) );
			removeListeners( event.target as IEventDispatcher );
		}
		private function errorHandler(event:IOErrorEvent):void
		{
			if( debug ) trace('Config.error');
			dispatchEvent( new ErrorEvent( ErrorEvent.ERROR ) );
			removeListeners( event.target as IEventDispatcher );
		}
		
		//
		private function progressHandler(event:ProgressEvent ):void
		{
			if ( debug ) trace( 'Config.progress', event.bytesLoaded, event.bytesTotal,( event.bytesLoaded / event.bytesTotal ) );
			if ( progressBar != null )
			{
				progressBar.update( event.bytesLoaded / event.bytesTotal );
			}
        }
		
		
		private function completeHandler(event:Event):void
		{
			
            var loader:URLLoader = URLLoader(event.target);
			var result:XML = new XML (loader.data);
			
			parseXML( result );
			
			removeListeners( event.target as IEventDispatcher );
			if ( progressBar != null )
			{
				progressBar.disappear();
			}
			
        }
		
		private function parseXML( xml:XML ):void 
		{
			
			var ns:Namespace = new Namespace( xml.namespace() );
			//default xml namespace = ns;
			xmlResults = xml;
			
			var name:String, value:String, node:*;
			for each( node in xmlResults.descendants() )
			{
				
				name = node.attribute( 'name' );
				value =  node.attribute( 'value' );
				instance[ StringUtil.removeSpecialChars( name ) ] = String( value );
				
			}
			dispatchEvent( new Event( Event.COMPLETE ) );
			
		}
		
		/**
		 * creates a new property
		 * @param	name variable name
		 * @param	value variable value
		 */
		static public function setProperty( name:String, value:* ):void
		{
			instance[ StringUtil.removeSpecialChars( name ) ] = value;
		}
		
		/**
		 * returns a property
		 * @param	name variable name
		 */
		static public function getProperty( name:String ):*
		{
			if ( name == 'count' )
			{
				
				if ( instance[ StringUtil.removeSpecialChars( name ) ] == null ) return 0;
				return instance[ StringUtil.removeSpecialChars( name ) ];
				
			}
			return instance[ StringUtil.trim( StringUtil.removeSpecialChars( name ) ) ];
		}
		
		
	}
	
}